use poker_lib::{PokerCard, PokerCards};

///每圈出牌的状态，根据状态决定出牌策略
pub struct TurnState {
    pub history_suit_piles: PokerCards,
    pub is_leading_player: bool,
    pub is_leading_next_player_id: bool,
    pub is_leading_partner: bool,
    pub is_leading_pre_player_id: bool,
    pub is_team_overtrick: bool,
    pub is_other_overtirck: bool,
    pub is_opponents_nil: bool,
    pub team_bid: i16,
    pub other_bid: i16,
    pub partner_player_id: usize,
    pub next_player_id: usize,
    pub pre_player_id: usize,
    pub team_bt_delta: i16,
    pub other_bt_delta: i16,
    pub team_match_score: i16,
    pub team_total_bags: i16,
    pub other_match_score: i16,
    pub other_total_bags: i16,
}

impl TurnState {
    pub fn new() -> Self {
        TurnState {
            history_suit_piles: PokerCards::new(),
            is_leading_player: false,
            is_leading_next_player_id: false,
            is_leading_partner: false,
            is_leading_pre_player_id: false,
            is_team_overtrick: false,
            is_other_overtirck: false,
            is_opponents_nil: false,
            team_bid: 0,
            other_bid: 0,
            partner_player_id: 0,
            next_player_id: 0,
            pre_player_id: 0,
            team_bt_delta: 0,
            other_bt_delta: 0,
            team_match_score: 0,
            team_total_bags: 0,
            other_match_score: 0,
            other_total_bags: 0,
        }
    }
}

pub struct TurnHandPileState {
    pub pile_suit_group: PokerCards,
    pub mid_cards: Vec<PokerCard>,
    pub playable_pile: Vec<PokerCard>,
    pub big_cards: Vec<PokerCard>,
    pub lowest_cards: Vec<PokerCard>,
    pub spades_pile: Vec<PokerCard>,
    ///空缺的花色
    pub void_suits: Vec<u8>,
    ///比较大的黑桃
    pub spades_count: i16,
}

impl TurnHandPileState {
    pub fn new() -> Self {
        TurnHandPileState {
            pile_suit_group: PokerCards::new(),
            mid_cards: vec![],
            playable_pile: vec![],
            big_cards: vec![],
            lowest_cards: vec![],
            spades_pile: vec![],
            void_suits: vec![],
            spades_count: 0,
        }
    }
}

///bid状态计算 hard bid 模式需要
pub struct TurnBidState {
    pub is_leading_player: bool,
    pub is_leading_partner: bool,
    pub is_last_player_bid: bool,
    pub partner_bid: i16,
    pub leading_bid: i16,
    pub pre_player_bid: i16,
    pub team_match_score: i16,
    pub team_total_bags: i16,
    pub other_match_score: i16,
    pub other_total_bags: i16,
    pub team_final_left_score: i16,
    pub other_final_left_score: i16,
    pub team_bags_dt: i16,
    pub other_bags_dt: i16,
}

impl TurnBidState {
    pub fn new() -> Self {
        TurnBidState {
            is_leading_player: false,
            is_leading_partner: false,
            is_last_player_bid: false,
            partner_bid: -1,
            leading_bid: 0,
            pre_player_bid: -1,
            team_match_score: 0,
            team_total_bags: 0,
            other_match_score: 0,
            other_total_bags: 0,
            team_final_left_score: 0,
            other_final_left_score: 0,
            team_bags_dt: 100,
            other_bags_dt: 100,
        }
    }
    // pub fn is_team_has_break_bag(&self) -> bool {
    //     return self.team_bags_dt <= 0
    // }
    // pub fn is_team_will_break_bags(&self)->bool {
    //     self.team_bags_dt <= 1
    // }
    // pub fn is_team_safe_trick(&self) -> bool {
    //     self.is_team_has_break_bag() ||(self.team_bags_dt>1 && self.team_bags_dt<100)
    // }
    // pub fn is_other_has_break_bag(&self) -> bool {
    //     return self.other_bags_dt <= 0
    // }
    // pub fn is_other_will_break_bags(&self)->bool {
    //     self.other_bags_dt <= 1
    // }
    // pub fn is_other_safe_trick(&self) -> bool {
    //     self.is_other_has_break_bag() ||(self.other_bags_dt>1 && self.other_bags_dt<100)
    // }
}

#[derive(Copy, Clone, Debug)]
pub struct TurnCard {
    pub seat_id: usize,
    pub card: PokerCard,
}

#[derive(Clone, Debug)]
pub struct TurnPlay {
    pub turn_cards: Vec<TurnCard>,
    pub max_seat_id: usize,
    // 本轮首出牌回合玩家
    pub leading_id: usize,
}

impl TurnPlay {
    pub fn new(seat_id: usize) -> Self {
        TurnPlay {
            turn_cards: vec![],
            max_seat_id: seat_id,
            leading_id: seat_id,
        }
    }

    pub fn compare_card(&self) -> usize {
        let turn_cards = &self.turn_cards;
        let leader_card = &turn_cards[0];
        let mut temp_max = self.get_card_score(&leader_card.card, &leader_card.card);
        let mut max_sid = leader_card.seat_id;
        for cards in turn_cards {
            let s = self.get_card_score(&leader_card.card, &cards.card);
            if s > temp_max {
                temp_max = s;
                max_sid = cards.seat_id;
            }
        }
        max_sid
    }

    fn get_card_score(&self, leader: &PokerCard, c: &PokerCard) -> u32 {
        let score;
        let tn = c.get_suit_num();
        // 处理A
        let tn_number: i16 = c.get_number() as i16;
        // 首牌花色
        let ltn = leader.get_suit_num();
        if tn.0 == 0 || tn.0 == 4 {
            // 黑桃和王牌永远最大
            score = tn_number as u32 * 100;
        } else {
            // 和首牌同花色
            if tn.0 == ltn.0 {
                score = tn_number as u32 * 10;
            } else {
                score = tn_number as u32;
            }
        }

        score
    }

    pub fn winning_card(&self) -> &TurnCard {
        let mut card: &TurnCard = self.leading_card();
        for turn_card in &self.turn_cards {
            if turn_card.seat_id == self.max_seat_id {
                card = turn_card;
                break;
            }
        }
        card
    }

    pub fn leading_card(&self) -> &TurnCard {
        &self.turn_cards[0]
    }

    //根据座位获取打的牌
    pub fn get_play_card_by_seat(&self, seat_id: usize) -> Option<&PokerCard> {
        for turn_card in &self.turn_cards {
            if turn_card.seat_id == seat_id {
                return Some(&turn_card.card);
            }
        }
        None
    }

    /// 获取本轮出牌的花色分组
    pub fn play_cards_of_suit(&self) -> PokerCards {
        let cards = &self.turn_cards;
        let mut poker_cards = PokerCards::new();
        for card in cards {
            poker_cards.add(card.card);
        }
        poker_cards
    }
    /// 获取当前轮是否是黑桃杀
    pub fn is_spades_break(&self) -> bool {
        let cards = &self.turn_cards;
        if cards.len() == 0 {
            return false;
        }
        let first_out_card = cards.first().unwrap();
        if first_out_card.card.is_trump_card() {
            return false;
        }
        for turn_card in cards {
            if turn_card.card.is_trump_card() {
                return true;
            }
        }
        return false;
    }
    //是黑桃杀 并且成功 返回当前出牌
    pub fn get_spades_break_win_card(&self) -> Option<&TurnCard> {
        let cards = &self.turn_cards;
        if cards.len() == 0 {
            return None;
        }
        let first_out_card = cards.first().unwrap();
        if first_out_card.card.is_trump_card() {
            return None;
        }
        let card = self.winning_card();
        if card.card.is_trump_card() {
            return Some(card);
        }
        None
    }
}
